import os
import json
import requests
from typing import Dict, List, Optional
import re
from config import XINGHE_API_KEY, XINGHE_BASE_URL, XINGHE_MODEL

class AnswerGenerator:
    """智能回答生成器"""
    
    def __init__(self):
        # 只使用星河大模型API
        self.api_key = XINGHE_API_KEY
        self.api_url = XINGHE_BASE_URL
        self.model_name = XINGHE_MODEL
        
    def generate(self, question: str, classification: Dict, retrieved_docs: List[Dict], context: List[Dict] = None) -> str:
        """生成回答"""
        # 检查是否是问候语
        if self._is_greeting(question):
            return self._generate_greeting_response(question)
        
        # 尝试调用API大模型生成回答
        try:
            return self._generate_api_answer(question, classification, retrieved_docs, context)
        except Exception as e:
            print(f"API调用失败: {e}")
            # 如果API调用失败，使用备用方案
            return self._generate_fallback_answer(question, classification, retrieved_docs)
    
    def _is_greeting(self, question: str) -> bool:
        """检查是否是问候语"""
        greeting_keywords = ['hello', 'hi', '你好', '您好', '在吗', '在不在']
        question_lower = question.lower()
        return any(keyword in question_lower for keyword in greeting_keywords)
    
    def _generate_greeting_response(self, question: str) -> str:
        """生成问候回复"""
        greeting_responses = [
            """# 🦀 Hello Rust!

很高兴认识你！我是你的Rust学习伙伴。

## 💪 我的能力

- **概念解释**：深入浅出地解释Rust概念
- **代码示例**：提供实用的代码示例
- **错误调试**：帮助解决编译和运行时问题
- **最佳实践**：分享Rust编程的最佳实践
- **可视化学习**：生成知识点图表帮助理解

## 🔥 立即开始

有什么Rust问题想要了解？我在这里等你！


---

### 📊 可视化学习

想要生成Rust知识点的可视化图表？点击这里进入 [可视化页面](/?tab=visualization) 生成知识点图表！

### 🎮 代码闯关

想要通过实践来巩固Rust知识吗？点击这里进入 [代码闯关](/?tab=challenges) 挑战相关练习！"""
        ]
        
        # 根据问题内容选择不同的回复
        question_lower = question.lower()
        if 'hello' in question_lower or 'hi' in question_lower:
            return greeting_responses[0]
        elif '你好' in question_lower:
            return greeting_responses[0]
        else:
            return greeting_responses[0]
    
    def _generate_api_answer(self, question: str, classification: Dict, retrieved_docs: List[Dict], context: List[Dict] = None) -> str:
        """调用星河大模型API生成回答"""
        try:
            # 构建提示词
            prompt = self._build_api_prompt(question, classification, retrieved_docs, context)
            
            # 调用星河大模型API
            headers = {
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.api_key}"
            }
            
            data = {
                "model": self.model_name,
                "messages": [
                    {"role": "system", "content": "你是一个专业的Rust编程语言助手，擅长回答各种Rust相关问题。请提供详细、准确、格式良好的回答，使用Markdown格式组织内容，包含适当的标题、代码块和列表。"},
                    {"role": "user", "content": prompt}
                ],
                "temperature": 0.7,
                "max_tokens": 2000  # 增加最大token数，以支持更详细的回答
            }
            
            # 确保API URL格式正确
            api_url = self.api_url
            if not api_url.startswith(('http://', 'https://')):
                api_url = f"https://{api_url}"
            
            response = requests.post(
                f"{api_url}/chat/completions",
                headers=headers,
                json=data,
                timeout=30
            )
            
            if response.status_code != 200:
                print(f"星河大模型API调用失败: {response.status_code} - {response.text}")
                return self._generate_fallback_answer(question, classification, retrieved_docs, context)
            
            result = response.json()
            
            # 确保正确提取content字段
            if "choices" in result and len(result["choices"]) > 0 and "message" in result["choices"][0]:
                answer = result["choices"][0]["message"]["content"]
            else:
                # 如果格式不符合预期，打印整个响应并使用备用方案
                print(f"API响应格式不符合预期: {result}")
                return self._generate_fallback_answer(question, classification, retrieved_docs, context)

            # 格式化回答
            answer = self._format_answer(answer)
            
            # 添加知识可视化和代码闯关的提示链接
            answer = self._add_learning_links(answer, question)
            
            return answer
            
        except Exception as e:
            print(f"星河大模型API调用异常: {str(e)}")
            return self._generate_fallback_answer(question, classification, retrieved_docs, context)

    def _format_answer(self, answer: str) -> str:
        """格式化从API返回的回答，确保可读性，特别优化代码块显示"""
        # 检查是否是JSON格式的响应，如果是，提取content字段
        if answer.startswith("{'id':") or answer.startswith('{'):
            try:
                # 尝试解析JSON
                import json
                if isinstance(answer, str):
                    # 替换单引号为双引号，以便json.loads可以解析
                    json_str = answer.replace("'", '"')
                    parsed = json.loads(json_str)
                    if "choices" in parsed and len(parsed["choices"]) > 0:
                        if "message" in parsed["choices"][0] and "content" in parsed["choices"][0]["message"]:
                            answer = parsed["choices"][0]["message"]["content"]
            except:
                # 如果解析失败，继续使用原始answer
                pass
        
        # 首先处理代码块，提取并暂存
        code_blocks = []
        code_pattern = r'```(\w+)?\n(.*?)\n```'
        
        def replace_code_block(match):
            language = match.group(1) or ''
            code_content = match.group(2)
            # 清理代码内容，移除多余的注释和空行
            cleaned_code = self._clean_code_content(code_content)
            code_blocks.append((language, cleaned_code))
            return f'__CODE_BLOCK_{len(code_blocks)-1}__'
        
        # 替换所有代码块为占位符
        answer = re.sub(code_pattern, replace_code_block, answer, flags=re.DOTALL)
        
        # 1. 将所有标题强制分离到单独的行
        # e.g., "abc ## title" -> "abc\n\n## title"
        answer = re.sub(r' (##+ )', r'\n\n\1', answer)

        # 2. 替换旧的 `### **...**` 格式
        answer = re.sub(r'### \*\*(.*?)\*\*', r'## \1', answer)

        # 3. 确保每个标题（现在都在自己的行上）前后都有空行
        lines = answer.split('\n')
        processed_lines = []
        for i, line in enumerate(lines):
            stripped_line = line.strip()
            if stripped_line.startswith('#'):
                # 在标题前添加空行（如果需要）
                if i > 0 and processed_lines and processed_lines[-1].strip() != '':
                    processed_lines.append('')
                processed_lines.append(stripped_line)
                # 在标题后添加空行（如果需要）
                if i + 1 < len(lines) and lines[i+1].strip() != '':
                    processed_lines.append('')
            else:
                processed_lines.append(line)
        answer = '\n'.join(processed_lines)

        # 4. 将三个以上的连续换行符压缩为两个
        answer = re.sub(r'\n{3,}', '\n\n', answer)

        # 5. 清理开头和结尾
        answer = answer.strip()
        
        # 6. 恢复代码块
        for i, (language, code_content) in enumerate(code_blocks):
            code_block = f"```{language}\n{code_content}\n```"
            answer = answer.replace(f'__CODE_BLOCK_{i}__', code_block)

        return answer
    
    def _clean_code_content(self, code_content: str) -> str:
        """清理代码内容，移除多余注释和格式化问题"""
        lines = code_content.split('\n')
        cleaned_lines = []
        
        for line in lines:
            # 移除行尾多余空白
            line = line.rstrip()
            
            # 跳过纯注释行（但保留代码中的注释）
            stripped = line.strip()
            if stripped.startswith('//') and not stripped.startswith('//='):
                # 如果是纯注释行且不在代码块内部，跳过
                continue
            elif stripped.startswith('/*') and stripped.endswith('*/'):
                # 单行块注释，跳过
                continue
            elif stripped.startswith('/*') or stripped.startswith('*'):
                # 多行块注释的开始行，跳过
                continue
            elif stripped.endswith('*/'):
                # 多行块注释的结束行，跳过
                continue
            else:
                # 保留代码行（包括包含注释的代码行）
                cleaned_lines.append(line)
        
        # 移除开头的空行但保留缩进
        while cleaned_lines and not cleaned_lines[0].strip():
            cleaned_lines.pop(0)
            
        # 移除结尾的空行
        while cleaned_lines and not cleaned_lines[-1].strip():
            cleaned_lines.pop()
            
        return '\n'.join(cleaned_lines)
    
    def _build_api_prompt(self, question: str, classification: Dict, retrieved_docs: List[Dict], context: List[Dict] = None) -> str:
        """构建API提示词"""
        prompt = f"""
请回答以下关于Rust编程的问题：{question}

## 回答要求

**重要：请直接提供回答，不要使用特定的结构化格式。**

### 回答要求
- 直接回答问题，语言要清晰易懂
- 提供一些代码示例来说明概念
- 保持回答简洁但有用
- 不需要遵循特定的三部分结构

### 格式要求
- 使用Markdown格式
- 适当使用标题、列表、代码块
- 代码示例要有适当的注释
- 保持整体格式简洁

请直接提供回答，不需要强制使用特定的结构。
        """
        
        # 添加上下文信息
        if context:
            prompt += "\n对话历史：\n"
            for turn in context[-2:]:  # 只保留最近2轮
                prompt += f"问：{turn['question']}\n答：{turn['answer'][:100]}...\n\n"
        
        # 添加相关知识库信息
        if retrieved_docs:
            prompt += "\n相关知识：\n"
            for doc in retrieved_docs[:2]:  # 只取前2个相关文档
                prompt += f"- {doc['topic']}: {doc['content']}\n"
        
        return prompt
    
    def _generate_fallback_answer(self, question: str, classification: Dict, retrieved_docs: List[Dict], context: List[Dict] = None) -> str:
        """生成备用回答，当API调用失败时使用"""
        # 根据问题类型生成基本的回答
        question_lower = question.lower()
        
        if "所有权" in question_lower:
            return """
# Rust所有权系统

Rust的所有权系统是其核心特性之一，旨在确保内存安全而无需垃圾回收器。

## 所有权规则

1. **每个值都有一个所有者**：在Rust中，每个值都有一个被称为"所有者"的变量。
2. **一次只能有一个所有者**：任何时候，一个值只能有一个所有者。
3. **当所有者离开作用域时，值将被释放**：当所有者（变量）离开其作用域时，Rust会自动调用Drop trait来释放资源。

## 示例代码

```rust
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // s1的所有权移动到s2
    
    // println!("{}", s1); // 这行会报错，因为s1不再拥有这个值
    println!("{}", s2); // 正确，s2是新的所有者
}
```

## 借用与引用

为了临时允许其他变量使用一个值而不取得所有权，Rust提供了"借用"机制：

```rust
fn main() {
    let s1 = String::from("hello");
    
    // 不可变借用
    let len = calculate_length(&s1);
    
    println!("'{}' 的长度是 {}", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
} // s离开作用域，但因为它没有所有权，所以不会丢弃
```
            """
        elif "借用" in question_lower:
            return """
# Rust借用规则

Rust的借用规则与所有权密切相关，确保内存安全的同时允许灵活的数据访问。

## 借用规则

1. **在同一时间，只能有一个可变引用**，或者**多个不可变引用**
2. **引用必须总是有效的**

## 不可变借用

```rust
fn main() {
    let s = String::from("hello");
    
    let r1 = &s; // 没问题
    let r2 = &s; // 没问题
    
    println!("{} 和 {}", r1, r2);
    // r1和r2在此之后不再使用
}
```

## 可变借用

```rust
fn main() {
    let mut s = String::from("hello");
    
    let r1 = &mut s; // 只能有一个可变引用
    
    r1.push_str(", world");
    println!("{}", r1);
}
```

## 悬垂引用

Rust编译器确保引用不会"悬垂"：

```rust
fn dangle() -> &String { // 错误：返回引用可能导致悬垂
    let s = String::from("hello");
    &s
} // s离开作用域并被丢弃，其内存被释放

// 正确的做法是返回String本身
fn no_dangle() -> String {
    let s = String::from("hello");
    s // s的所有权被移动给调用者
}
```
            """
        elif "生命周期" in question_lower:
            return """
# Rust生命周期

生命周期是Rust中一个重要的概念，用于确保引用在其所指向的数据有效期间始终有效。

## 生命周期注解语法

生命周期注解以`'`开头，通常使用小写字母如`'a`、`'b`等。

```rust
&'a T     // 一个引用T，生命周期为'a
&'a mut T // 一个可变引用T，生命周期为'a
```

## 函数签名中的生命周期

```rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}
```

这个函数签名表示：返回值的生命周期将与输入参数中较短的那个相同。

## 结构体中的生命周期

```rust
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael...");
    let first_sentence = novel.split('.').next().expect("Could not find a '.'");
    
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}
```

## 生命周期省略规则

在某些情况下，Rust允许省略生命周期注解：

1. 每个输入参数都有自己的生命周期
2. 如果只有一个输入生命周期参数，那么所有输出生命周期都与之相同
3. 如果有多个输入生命周期参数，但其中一个是`&self`或`&mut self`，那么所有输出生命周期都与`self`相同
            """
        else:
            return f"""
# 关于您的问题：{question}

很抱歉，我目前无法提供详细的回答。不过，我可以为您提供一些学习Rust的建议：

1. **官方文档**：[Rust程序设计语言](https://doc.rust-lang.org/book/)
2. **在线练习**：[Rustlings](https://github.com/rust-lang/rustlings)
3. **社区资源**：[Rust用户论坛](https://users.rust-lang.org/)

如果您有具体的Rust问题，建议您尝试重新表述或提供更多上下文，这样我可能能够提供更有帮助的回答。
            """
    
    def _add_learning_links(self, answer: str, question: str) -> str:
        """不再添加学习链接，保持回答简洁"""
        return answer
    
    def _generate_mock_answer(self, question: str, classification: Dict, retrieved_docs: List[Dict], context: List[Dict] = None) -> str:
        """生成模拟API回答（用于测试）"""
        # 根据问题类型生成不同的回答
        if classification['label'] == 'definition':
            return self._generate_mock_definition(question)
        elif classification['label'] == 'usage':
            return self._generate_mock_usage(question)
        elif classification['label'] == 'error_debug':
            return self._generate_mock_error_debug(question)
        elif classification['label'] == 'comparison':
            return self._generate_mock_comparison(question)
        else:
            return self._generate_mock_faq(question)
    
    def _generate_mock_definition(self, question: str) -> str:
        """生成定义类问题的模拟回答"""
        topic = question.replace('是什么', '').replace('？', '').replace('什么意思', '').strip()
        
        # 根据不同主题生成不同的回答
        if '所有权' in topic:
            return """# Rust所有权系统详解

所有权(Ownership)是Rust编程语言的核心特性之一，它确保了内存安全而无需垃圾回收器。

## 所有权三大规则

1. 每个值都有一个所有者
2. 同一时间只能有一个所有者  
3. 当所有者离开作用域时，值将被丢弃

## 实际应用示例

```rust
fn main() {
    // s1 拥有字符串的所有权
    let s1 = String::from("Hello");
    println!("s1 = {}", s1);
    
    // 所有权转移给 s2
    let s2 = s1;
    // println!("s1 = {}", s1); // 这行会报错！所有权已转移
    
    println!("s2 = {}", s2);
    
    // 使用 clone() 可以深拷贝数据
    let s3 = s2.clone();
    println!("s2 = {}, s3 = {}", s2, s3);
}
```

## 借用与引用

Rust还提供了借用(Borrowing)机制，允许在不转移所有权的情况下访问数据：

```rust
fn calculate_length(s: &String) -> usize {  // 接收引用
    s.len()
}  // s 离开作用域，但没有所有权，所以不会丢弃

fn main() {
    let s1 = String::from("Hello");
    let len = calculate_length(&s1);  // 传递引用
    println!("'{}' 的长度是 {}", s1, len);  // s1 仍然有效
}
```

## 所有权优势

- 内存安全：编译时防止常见的内存错误
- 零成本抽象：运行时没有额外开销
- 并发安全：防止数据竞争

所有权系统是Rust最独特的特性，掌握它对于编写高效、安全的Rust代码至关重要。"""
        
        elif '生命周期' in topic:
            return """# Rust生命周期详解

生命周期(Lifetimes)是Rust中用来确保引用有效性的机制，它告诉编译器引用需要存活多久。

## 生命周期标注

生命周期使用撇号(`'`)表示，如`'a`、`'b`等：

```rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn main() {
    let string1 = String::from("长字符串");
    let string2 = "短";
    
    let result = longest(string1.as_str(), string2);
    println!("最长的字符串是: {}", result);
}
```

## 生命周期省略规则

Rust有一些规则允许省略生命周期标注：

1. 每个引用参数都有它自己的生命周期参数
2. 如果只有一个输入生命周期参数，那么它被赋予所有输出生命周期参数
3. 如果有多个输入生命周期参数，但其中一个是&self或&mut self，那么self的生命周期被赋予所有输出生命周期参数

## 结构体中的生命周期

```rust
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().expect("无法找到句号");
    
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}
```

## 生命周期与泛型

生命周期可以与泛型参数一起使用：

```rust
struct Ref<'a, T: 'a> {
    value: &'a T,
}

fn main() {
    let x = 5;
    let r = Ref { value: &x };
    
    println!("r.value = {}", r.value);
}
```

生命周期是Rust类型系统的重要组成部分，它确保了引用的安全性，防止了悬垂指针等问题。"""
        
        else:
            return """# {topic}详解

{topic}是Rust编程语言中的重要概念。

## 基本概念

{topic}在Rust中扮演着关键角色，它帮助开发者编写更安全、更高效的代码。

## 代码示例

```rust
fn main() {{
    // {topic}的基本用法示例
    let example = "Hello, Rust!";
    println!("结果: {{}}", example);
}}
```

## 实际应用

在实际开发中，{topic}可以用于多种场景，包括：

- 提高代码安全性
- 优化性能
- 简化复杂逻辑

## 最佳实践

使用{topic}时，建议遵循以下最佳实践：

1. 深入理解其工作原理
2. 在适当场景下使用
3. 遵循Rust的编程规范

{topic}是Rust生态系统中的重要组成部分，掌握它将有助于你成为更优秀的Rust开发者。""".format(topic=topic)
    
    def _generate_mock_usage(self, question: str) -> str:
        """生成用法类问题的模拟回答"""
        topic = question.replace('如何使用', '').replace('怎么用', '').replace('？', '').strip()
        
        return """# {topic}使用指南

## 核心概念

{topic}是Rust中的重要概念，下面是一个清晰的示例：

```rust
fn main() {{
    // {topic}的使用示例
    let example = "Hello, Rust!";
    println!("结果: {{}}", example);
}}
```

## 进阶技巧

当你掌握了基本用法后，可以尝试以下进阶技巧：

1. 最佳实践：遵循Rust的编程规范
2. 性能优化：了解{topic}的性能特点
3. 错误处理：正确处理可能出现的错误情况

## 常见问题

在使用{topic}时，开发者可能会遇到以下问题：

- 问题1：如何选择合适的配置参数？
  - 解决方案：根据具体需求选择参数
  
- 问题2：如何处理边界情况？
  - 解决方案：添加适当的检查和错误处理

## 实际项目应用

在实际项目中，{topic}可以用于：

- 构建高性能系统
- 确保内存安全
- 简化复杂逻辑

## 学习资源

想要深入学习{topic}？以下资源可能会帮助你：

- Rust官方文档
- 社区教程和示例
- 实践项目案例

通过不断实践和学习，你将能够更加熟练地使用{topic}来解决实际问题。""".format(topic=topic)
    
    def _generate_mock_error_debug(self, question: str) -> str:
        """生成错误调试类问题的模拟回答"""
        # 尝试从问题中提取错误类型
        error_type = "编译错误"
        if "borrow" in question.lower() or "借用" in question:
            error_type = "借用检查错误"
        elif "lifetime" in question.lower() or "生命周期" in question:
            error_type = "生命周期错误"
        elif "ownership" in question.lower() or "所有权" in question:
            error_type = "所有权错误"
            
        return """## {error_type}调试指南

### 🎯 错误分析

{error_type}通常发生在以下情况：

- 违反了Rust的安全规则
- 引用使用不当
- 生命周期标注缺失或不正确

### 💡 常见错误示例

下面是一个典型的{error_type}示例：

```rust
fn main() {{
    let mut s = String::from("hello");
    
    let r1 = &s; // 不可变引用
    let r2 = &s; // 另一个不可变引用
    println!("r1: {{}}, r2: {{}}", r1, r2);
    
    // let r3 = &mut s; // 这会导致错误！不能在已有不可变引用时创建可变引用
    // println!("r3: {{}}", r3);
}}
```

### 🔄 解决方案

针对{error_type}，可以尝试以下解决方案：

1. **调整引用作用域**：确保引用不会相互冲突
2. **正确标注生命周期**：为复杂引用关系添加生命周期标注
3. **使用克隆**：在必要时使用clone()避免所有权问题

```rust
fn main() {{
    let mut s = String::from("hello");
    
    {{
        let r1 = &s; // 不可变引用
        let r2 = &s; // 另一个不可变引用
        println!("r1: {{}}, r2: {{}}", r1, r2);
    }} // r1和r2离开作用域
    
    let r3 = &mut s; // 现在可以创建可变引用
    println!("r3: {{}}", r3);
}}
```

### 🚀 调试技巧

当遇到{error_type}时，可以尝试以下调试技巧：

1. **仔细阅读错误信息**：Rust编译器通常会提供详细的错误描述
2. **使用IDE支持**：现代IDE可以高亮显示错误位置
3. **逐步简化代码**：将复杂代码分解为简单部分，逐步定位问题

### 📚 预防措施

预防{error_type}的最佳实践：

- 深入理解Rust所有权系统
- 遵循Rust的编程规范
- 使用适当的引用模式
- 定期进行代码审查

通过掌握这些技巧，你将能够更有效地解决{error_type}，编写出更加健壮的Rust代码。""".format(error_type=error_type)
    
    def _generate_mock_comparison(self, question: str) -> str:
        """生成比较类问题的模拟回答"""
        # 尝试从问题中提取比较的主题
        topic1 = "概念A"
        topic2 = "概念B"
        
        # 简单的关键词匹配
        if "所有权" in question and "借用" in question:
            topic1 = "所有权"
            topic2 = "借用"
        elif "String" in question and "&str" in question:
            topic1 = "String"
            topic2 = "&str"
        elif "Vec" in question and "数组" in question:
            topic1 = "Vec"
            topic2 = "数组"
            
        return """## {topic1}与{topic2}比较

### 🎯 基本概念

**{topic1}**和**{topic2}**都是Rust中的重要概念，但它们有不同的用途和特性。

### 💡 主要区别

| 特性 | {topic1} | {topic2} |
|------|----------|----------|
| 内存管理 | 通常拥有数据 | 通常引用数据 |
| 性能 | 可能有额外开销 | 通常更高效 |
| 灵活性 | 更灵活 | 使用场景更特定 |
| 安全性 | 提供不同的安全保证 | 提供不同的安全保证 |

### 🔄 使用场景

**{topic1}适用于：**
- 需要拥有数据的场景
- 需要修改数据的场景
- 长期存储数据

**{topic2}适用于：**
- 临时访问数据
- 不需要修改数据
- 性能敏感的场景

### 🚀 代码示例

```rust
fn main() {{
    // {topic1}的使用示例
    let example1 = "示例数据";
    println!("{topic1}示例: {{}}", example1);
    
    // {topic2}的使用示例
    let example2 = "示例数据";
    println!("{topic2}示例: {{}}", example2);
}}
```

### 📚 选择建议

在选择使用{topic1}还是{topic2}时，考虑以下因素：

1. **性能需求**：如果性能是关键考虑因素，{topic2}可能更合适
2. **灵活性需求**：如果需要更多的灵活性，{topic1}可能更好
3. **代码可读性**：选择使代码更清晰、更易理解的选项

### 🎯 总结

{topic1}和{topic2}各有优势，没有绝对的"更好"，只有"更适合"。理解它们的区别和适用场景，将帮助你做出正确的选择，编写出更加高效、安全的Rust代码。""".format(topic1=topic1, topic2=topic2)
    
    def _generate_mock_faq(self, question: str) -> str:
        """生成FAQ类问题的模拟回答"""
        return """## Rust常见问题解答

### 🎯 初学者常见问题

**Q1: Rust值得学习吗？**

A: 绝对值得！Rust是一门现代化的系统编程语言，具有以下优势：
- 内存安全：无需垃圾回收器即可防止常见的内存错误
- 高性能：与C/C++相媲美的性能
- 并发安全：编译时防止数据竞争
- 强大的工具链：包管理器Cargo、格式化工具rustfmt等

**Q2: Rust学习曲线陡峭吗？**

A: Rust确实有一些独特的概念（如所有权和生命周期），这些可能会让初学者感到挑战。但是：
- 一旦理解了核心概念，你会发现它们非常直观
- 编译器提供了极其详细的错误信息，帮助学习和调试
- 社区资源丰富，有大量教程和示例代码

### 💡 所有权与借用问题

**Q3: 什么是所有权？**

A: 所有权是Rust的核心特性，它确保内存安全而无需垃圾回收器。所有权遵循三大规则：
1. 每个值都有一个所有者
2. 同一时间只能有一个所有者
3. 当所有者离开作用域时，值将被丢弃

**Q4: 如何解决借用检查器错误？**

A: 常见的解决方法包括：
- 调整引用的作用域
- 使用克隆数据
- 重新设计数据结构
- 使用智能指针如Rc或RefCell

### 🔄 生命周期问题

**Q5: 生命周期是什么？为什么需要它？**

A: 生命周期是Rust用来确保引用有效性的机制。它告诉编译器引用需要存活多久，防止悬垂指针等问题。虽然生命周期标注看起来复杂，但在很多情况下，Rust可以自动推断生命周期。

**Q6: 什么时候需要显式标注生命周期？**

A: 当编译器无法自动推断生命周期时，你需要显式标注。常见情况包括：
- 函数返回引用
- 结构体包含引用
- 多个引用参数且返回值是引用

### 🚀 实际应用问题

**Q7: Rust适合哪些应用场景？**

A: Rust适用于多种场景：
- 系统编程：操作系统、嵌入式设备
- Web后端：高性能网络服务
- 命令行工具：高效、可靠的CLI应用
- WebAssembly：在浏览器中运行高性能代码
- 区块链：安全、高效的智能合约

**Q8: Rust生态系统如何？**

A: Rust生态系统正在快速发展：
- crates.io：官方包注册表，有大量高质量的库
- 活跃的社区：论坛、Discord、Reddit等
- 丰富的学习资源：官方文档、书籍、教程
- 企业采用：越来越多的公司使用Rust

### 📚 学习资源推荐

**Q9: 有哪些推荐的学习资源？**

A: 以下是一些高质量的学习资源：
- 《The Rust Programming Language》官方书籍
- Rust by Example：通过示例学习Rust
- Rustlings：交互式练习
- Exercism上的Rust课程
- YouTube上的Rust视频教程

**Q10: 如何参与Rust社区？**

A: 参与Rust社区的多种方式：
- 加入官方论坛和用户论坛
- 参与本地Rust聚会
- 为开源项目做贡献
- 在社交媒体上关注Rust相关账号

### 🎯 总结

Rust是一门强大而安全的编程语言，虽然学习曲线可能有些陡峭，但掌握它将使你能够编写出更安全、更高效的代码。不要害怕犯错，Rust编译器是你最好的老师！"""
    
    def _generate_fallback_answer(self, question: str, classification: Dict, retrieved_docs: List[Dict], context: List[Dict] = None) -> str:
        """生成备用回答（当API调用失败时）"""
        question_lower = question.lower()
        
        # 根据问题类型生成不同的回答
        if classification['label'] == 'definition':
            return self._generate_definition_fallback(question)
        elif classification['label'] == 'usage':
            return self._generate_usage_fallback(question)
        elif classification['label'] == 'error_debug':
            return self._generate_error_debug_fallback(question)
        elif classification['label'] == 'comparison':
            return self._generate_comparison_fallback(question)
        else:
            return self._generate_faq_fallback(question)
    
    def _generate_definition_fallback(self, question: str) -> str:
        """生成定义类问题的备用回答"""
        topic = question.replace('是什么', '').replace('？', '').replace('什么意思', '')
        answer = """## 基本概念

**{topic}**是Rust编程语言中的一个重要概念。

### 核心特点
- 这是Rust的核心特性之一
- 确保内存安全和线程安全
- 编译时检查，运行时零开销
- 提供强大的抽象能力

### 简短示例
```rust
fn main() {{
    // {topic}的使用示例
    let example = "Hello, Rust!";
    println!("{{}}", example);
}}
```
""".format(topic=topic)
        return self._add_learning_links(answer, question)
    
    def _generate_usage_fallback(self, question: str) -> str:
        """生成用法类问题的备用回答"""
        topic = question.replace('怎么', '').replace('如何', '').replace('使用', '').replace('？', '')
        answer = """## 使用方法

**{topic}**是Rust中的重要概念。

### 实际应用
- 用于解决特定问题
- 提高代码安全性
- 优化性能表现

### 简短示例
```rust
fn main() {{
    // {topic}的使用示例
    let result = example_function();
    println!("结果: {{}}", result);
}}

fn example_function() -> i32 {{
    42
}}
```

### 核心要点
1. 遵循Rust的所有权规则
2. 使用适当的借用和引用
3. 注意生命周期管理
""".format(topic=topic)
        return self._add_learning_links(answer, question)
    
    def _generate_error_debug_fallback(self, question: str) -> str:
        """生成错误调试类问题的备用回答"""
        topic = question.replace('错误', '').replace('问题', '').replace('？', '')
        answer = """## 错误分析

您遇到的**{topic}**通常是由于以下原因：

### 常见原因
- 借用检查器规则违反
- 生命周期不匹配
- 类型不匹配
- 所有权问题

### 解决方案
```rust
// 错误代码示例
let mut v = vec![1, 2, 3];
let first = &v[0];
v.push(4); // 编译错误

// 正确代码
let mut v = vec![1, 2, 3];
v.push(4);
let first = &v[0]; // 正确
```
""".format(topic=topic)
        return self._add_learning_links(answer, question)
    
    def _generate_comparison_fallback(self, question: str) -> str:
        """生成对比类问题的备用回答"""
        topic = question.replace('区别', '').replace('不同', '').replace('比较', '').replace('？', '')
        answer = """## 对比分析

**{topic}**的主要差异：

### 核心差异
| 特性 | Rust | 其他语言 |
|------|------|----------|
| 内存管理 | 所有权系统 | 垃圾回收/手动管理 |
| 并发安全 | 编译时检查 | 运行时检查 |
| 性能 | 零开销抽象 | 可能有运行时开销 |

### 简短示例
```rust
// Rust 示例
let s = String::from("hello");
// 所有权自动管理
```
""".format(topic=topic)
        return self._add_learning_links(answer, question)
    
    def _generate_faq_fallback(self, question: str) -> str:
        """生成FAQ类问题的备用回答"""
        topic = question.replace('？', '')
        answer = """## 问题解答

关于**{topic}**的详细解答：

### 基本概念
这是一个常见的问题，涉及到Rust的学习路径和最佳实践。

### 简短示例
```rust
fn main() {{
    // 基础示例
    println!("Hello, Rust!");
}}
```

### 学习建议
1. 从官方文档开始学习
2. 多做练习项目
3. 参与社区讨论
""".format(topic=topic)
        return self._add_learning_links(answer, question)